﻿using System;
using System.IO;
using System.ComponentModel;
using System.Xml;

namespace MassIntellect.WorkIt.Frames
{
	[Browsable(true)]
	[Description("Файловый хранитель. Сохраняет передаваемый поток в файл.")]
	public class StreamFileSaver : WorkFrame
	{
		[Serialize]
		[Browsable(true)]
		[Description("Ключ в сигнале с сохраняемым потоком. Поток должен быть совместим с типом Stream и быть доступным для чтения.")]
		[Category("Сигнал")]
		[DefaultValue(typeof(string), "Content")]
		public string ContentKey { get; set; }

		private Stream GetContent(PulseArgs args)
		{
			var key = ContentKey.IsEmpty() ? "Content" : ContentKey;
			return args.ContainsKey(key) ?
				args[key] as Stream : null;
		}

		/// <summary>
		/// Каталог, в котором будет сохранятся файл
		/// </summary>
		[Serialize(IgnoreDefault = true)]
		[Browsable(true)]
		[Description("Каталог в котором будет сохранен поток.")]
		[Category("Файловая система")]
		public string Directory
		{
			get
			{
				return _Directory;
			}
			set
			{
#if !DEBUG
                try
#endif
				{
					if (_Directory != value && !value.IsEmpty() && !System.IO.Directory.Exists(value))
						System.IO.Directory.CreateDirectory(value);
					_Directory = value;
				}
#if !DEBUG
                catch
                {
                }
#endif
			}
		}
		private string _Directory;

		/// <summary>
		/// Ключ аргумента "Имя файла"
		/// </summary>
		[Serialize(IgnoreDefault = true)]
		[Browsable(true)]
		[Description("Ключ в сигнале с именем файла. В имени файла может быть использованы подкаталоги и полный путь с диском.")]
		[Category("Сигнал")]
		[DefaultValue(typeof(string), "FileName")]
		public string FileNameKey { get; set; }

		/// <summary>
		/// Ключ аргумента "Подкаталог"
		/// </summary>
		[Serialize(IgnoreDefault = true)]
		[Browsable(true)]
		[Description("Ключ в сигнале с подкаталогом в котором будет сохранен поток.")]
		[Category("Сигнал")]
		[DefaultValue(typeof(string), "Content")]
		public string SubDirKey { get; set; }

		/// <summary>
		/// Расширение файла
		/// </summary>
		[Serialize(IgnoreDefault = true)]
		[Browsable(true)]
		[Description("Ключ в сигнале с расширением файла с котором будет сохранен поток.")]
		[Category("Сигнал")]
		[DefaultValue(typeof(string), "Content")]
		public string ExtensionKey { get; set; }

		private string GetFullPath(PulseArgs args)
		{
			string dir = Path.Combine(PathExtension.CorrectPath(Directory), PathExtension.CorrectPath(args[SubDirKey].GoString())), fn;
			dir = Path.Combine(dir, PathExtension.CorrectPath(args[FileNameKey].GoString() + '.' + (ExtensionKey ?? "xml")));
			if (!(fn = Path.GetDirectoryName(dir)).IsEmpty() && !System.IO.Directory.Exists(fn))
				System.IO.Directory.CreateDirectory(fn);
			return dir;
		}

		protected override void protectedPulse(PulseArgs args)
		{
			Stream stream;
			if ((stream = GetContent(args)) != null)
			{
				string fn;
				using (var fs = new FileStream(fn = PathExtension.GetAlternativeFilePath(
					GetFullPath(args)), FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
				{
					var buff = new byte[1024];
					int readed;
					while ((readed = stream.Read(buff, 0, buff.Length)) > 0)
						fs.Write(buff, 0, readed);
					Log("Сохранен: {0}", fn);
				}
			}
			base.protectedPulse(args);
		}
	}
}
